package ai.博弈树;

import org.omg.PortableInterceptor.INACTIVE;

import java.util.Date;
import java.util.Random;
import java.util.Scanner;

/**
 * 博弈树主程序
 */
public class GameTree {

    //棋盘内容
    private char[][] chess;

    public static void main(String[] args) {
        GameTree gameTree = new GameTree();

        gameTree.init();
        gameTree.begin();

    }

    GameTree() {
        this.chess = new char[3][3];
        for (int i = 0;i<3;i++) {
            for (int j = 0;j<3;j++) {
                chess[i][j] = '-';
            }
        }
    }

    /**
     * 初始化游戏
     */
    private void init() {
        Scanner scanner = new Scanner(System.in);
        //玩家先手还是后手，默认先手
        int firstBegin;
        System.out.println("=====欢迎使用人机对战小游戏=====");
        System.out.println("请选择先手或者后手，先手输入0，后手输入1：");
        firstBegin = scanner.nextInt();
        System.out.println("=======开始游戏，绘制棋盘=======");

        //人后手需要随机一个位置在棋盘上
        if (1 == firstBegin) {
            chess[1][1] = 'X';
        }
    }

    private void begin() {
        Scanner scanner = new Scanner(System.in);
        int x,y;
        while (true) {
            System.out.println("=========================");
            drawView();
            System.out.println("请选择你要下的x坐标位置（0-2）：");
            x = scanner.nextInt();
            System.out.println("请选择你要下的y坐标位置（0-2）：");
            y = scanner.nextInt();
            if (x > 2 || y > 2 || x < 0 || y < 0) {
                System.out.println("输入坐标不正确！");
            } else if (chess[x][y] != '-') {
                System.out.println("输入坐标已经下过棋子！");
            } else {
                chess[x][y] = 'O';
                System.out.println("下棋成功！");
            }
            AIPoint();

            int a = isWin();
            switch (a) {
                case -1:
                    System.out.println("人获胜");
                    return;
                case 1:
                    System.out.println("AI获胜");
                    return;
                case 0:
                    System.out.println("平局");
                    return;
                default:
                    break;
            }
        }
    }

    /**
     * 绘制棋盘
     */
    private void drawView() {
        System.out.println("=======当前局势如下=======");
        for (int i = 0;i<3;i++) {
            for (int j = 0;j<3;j++) {
                System.out.print(chess[i][j] + "\t");
            }
            System.out.println();
        }
        System.out.println("=========================");
    }

    /**
     * 电脑按照极大极小值算法进行下棋
     */
    private void AIPoint() {
        int maxScore = Integer.MIN_VALUE;
        int maxX = 0,maxY = 0;

        FOR:
        for (int x = 0;x<3;x++) {
            for (int y = 0;y<3;y++) {
                //是空位置可以下棋
                if (chess[x][y] == '-') {
                    int score = AITestPoint(x, y);
                    if (score == Integer.MIN_VALUE) {
                        maxX = -1;
                        maxY = -1;
                        break FOR;
                    }
                    else if (score > maxScore) {
                        maxX = x;
                        maxY = y;
                        maxScore = score;
                    }
                }
            }
        }
        try{
            chess[maxX][maxY] = 'X';
        }catch (Exception ignored){}

    }

    /**
     *
     * @param x 坐标
     * @param y 坐标
     * @return  ai-p分数
     */
    private int AITestPoint(int x, int y){
        int pScore = 0;
        int aiScore = 0;
        chess[x][y] = 'X';

        for (int xx = 0;xx<3;xx++) {
            int AIEmptyXCount = 0;
            int AIEmptyYCount = 0;
            int pEmptyXCount = 0;
            int pEmptyYCount = 0;
            //有人类下棋的位置
            int pXCount = 0;
            int pYCount = 0;
            for (int yy = 0;yy<3;yy++) {
                //空都可以加
                if (chess[xx][yy] == '-') {
                    AIEmptyXCount++;
                    pEmptyXCount++;
                }
                if (chess[yy][xx] == '-') {
                    AIEmptyYCount++;
                    pEmptyYCount++;
                }
                //为X只给AI加
                if (chess[xx][yy] == 'X') {
                    AIEmptyXCount++;
                }
                if (chess[yy][xx] == 'X') {
                    AIEmptyYCount++;
                }
                //为O只给人加
                if (chess[xx][yy] == 'O') {
                    pEmptyXCount++;
                    pXCount++;
                }
                if (chess[yy][xx] == 'O') {
                    pEmptyYCount++;
                    pYCount++;
                }
            }
            if (AIEmptyXCount == 3) aiScore++;
            if (AIEmptyYCount == 3) aiScore++;
            if (pEmptyXCount == 3) pScore++;
            if (pEmptyYCount == 3) pScore++;

            if (pXCount >= 2) {
                for (int yy = 0;yy<3;yy++) {
                    if (chess[xx][yy] == '-') {
                        chess[xx][yy] = 'X';
                        chess[x][y] = '-';
                        return Integer.MIN_VALUE;
                    }
                }
            }

            if (pYCount >= 2) {
                for (int yy = 0;yy<3;yy++) {
                    if (chess[yy][xx] == '-') {
                        chess[yy][xx] = 'X';
                        chess[x][y] = '-';
                        System.out.println("abc");
                        return Integer.MIN_VALUE;
                    }
                }
            }
        }


        int AIEmptyXCount = 0;
        int AIEmptyYCount = 0;
        int pEmptyXCount = 0;
        int pEmptyYCount = 0;

        //有人类下棋的位置
        int pXCount = 0;
        int pYCount = 0;

        for (int xx = 0;xx<3;xx++) {
            //空都可以加
            if (chess[xx][xx] == '-') {
                AIEmptyXCount++;
                pEmptyXCount++;
            }
            if (chess[xx][2-xx] == '-') {
                AIEmptyYCount++;
                pEmptyYCount++;
            }
            //为O只给AI加
            if (chess[xx][xx] == 'X') {
                AIEmptyXCount++;
            }
            if (chess[xx][2-xx] == 'X') {
                AIEmptyYCount++;
            }
            //为X只给人加
            if (chess[xx][xx] == 'O') {
                pEmptyXCount++;
                pXCount++;
            }
            if (chess[xx][2-xx] == 'O') {
                pEmptyYCount++;
                pYCount++;
            }
        }
        if (AIEmptyXCount == 3) aiScore++;
        if (AIEmptyYCount == 3) aiScore++;
        if (pEmptyXCount == 3) pScore++;
        if (pEmptyYCount == 3) pScore++;

        if (pXCount >= 2) {
            for (int xx = 0;xx<3;xx++) {
                if (chess[xx][xx] == '-') {
                    chess[xx][xx] = 'X';
                    chess[x][y] = '-';
                    return Integer.MIN_VALUE;
                }
            }
        }

        if (pYCount >= 2) {
            for (int xx = 0;xx<3;xx++) {
                if (chess[xx][2-xx] == '-') {
                    chess[xx][2-xx] = 'X';
                    chess[x][y] = '-';
                    return Integer.MIN_VALUE;
                }
            }
        }

        chess[x][y] = '-';
        return aiScore - pScore;
    }

    private int isWin(){
        int count = 0;
        for (int x = 0;x<3;x++) {
            int aCountX = 0;
            int pCountX = 0;
            int aCountY = 0;
            int pCountY = 0;
            for (int y = 0;y<3;y++) {
                if (chess[x][y] != '-') count++;
                if (chess[x][y] == 'X') {
                    aCountX++;
                }
                if (chess[y][x] == 'X') {
                    aCountY++;
                }
                if (chess[x][y] == 'O') {
                    pCountX++;
                }
                if (chess[y][x] == 'O') {
                    pCountY++;
                }
            }
            if (aCountX == 3 || aCountY == 3) return 1;
            if (pCountX == 3 || pCountY == 3) return -1;
        }
        if (count == 9) return 0;

        int aCountX = 0;
        int pCountX = 0;
        int aCountY = 0;
        int pCountY = 0;
        for (int x = 0;x<3;x++) {
            if (chess[x][x] == 'X') {
                aCountX++;
            }
            if (chess[x][2-x] == 'X') {
                aCountY++;
            }
            if (chess[x][x] == 'O') {
                pCountX++;
            }
            if (chess[x][2-x] == 'O') {
                pCountY++;
            }
        }
        if (aCountX == 3 || aCountY == 3) return 1;
        if (pCountX == 3 || pCountY == 3) return -1;

        return 2;
    }


}